home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / db / esm-3.1 / esm-3 / usr / local / sm / src / diskproc / writeLocalDisk.c < prev   
Encoding:
C/C++ Source or Header  |  1996-05-05  |  8.2 KB  |  297 lines

  1. /*
  2.  *   $RCSfile: writeLocalDisk.c,v $  
  3.  *   $Revision: 1.2 $  
  4.  *   $Date: 1996/05/04 23:51:48 $      
  5.  */ 
  6. /**********************************************************************
  7. * EXODUS Database Toolkit Software
  8. * Copyright (c) 1991 Computer Sciences Department, University of
  9. *                    Wisconsin -- Madison
  10. * All Rights Reserved.
  11. *
  12. * Permission to use, copy, modify and distribute this software and its
  13. * documentation is hereby granted, provided that both the copyright
  14. * notice and this permission notice appear in all copies of the
  15. * software, derivative works or modified versions, and any portions
  16. * thereof, and that both notices appear in supporting documentation.
  17. *
  18. * THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY OF WISCONSIN --
  19. * MADISON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION.  
  20. * THE DEPARTMENT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
  21. * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  22. *
  23. * The EXODUS Project Group requests users of this software to return 
  24. * any improvements or extensions that they make to:
  25. *
  26. *   EXODUS Project Group 
  27. *     c/o David J. DeWitt and Michael J. Carey
  28. *   Computer Sciences Department
  29. *   University of Wisconsin -- Madison
  30. *   Madison, WI 53706
  31. *
  32. *     or exodus@cs.wisc.edu
  33. *
  34. * In addition, the EXODUS Project Group requests that users grant the 
  35. * Computer Sciences Department rights to redistribute these changes.
  36. **********************************************************************/
  37. #include "sysdefs.h"
  38. #include <sys/file.h>
  39. #include "ess.h"
  40. #include "checking.h"
  41. #include "trace.h"
  42. #include "error.h"
  43. #include "list.h"
  44. #include "tid.h"
  45. #include "io.h"
  46. #include "lock.h"
  47. #include "object.h"
  48. #include "msgdefs.h"
  49. #include "disk.h"
  50. #include "queues.h"
  51. #include "diskproc_globals.h"
  52. #include "diskproc_intfuncs.h"
  53. #include "diskproc_extfuncs.h"
  54.  
  55.  
  56. extern char        *ShmAddress;
  57. extern int        Fd;
  58.  
  59. #ifdef DISKPROC_MAKE
  60. /* see comments below where Shmstruct is used. */
  61. extern struct shmid_ds Shmstruct;
  62. #endif DISKPROC_MAKE
  63.  
  64.  
  65.  
  66. #ifdef DISKPROC_MAKE
  67. static void
  68. generateVector(
  69.     DISKMSG    *message,
  70.     struct  iovec  ioPageVec[],
  71.     int&    vecSize 
  72. )
  73. {
  74.     int     amountInBuf = 0;
  75.     int        diskVecUsed = 0;
  76.     int     i;
  77.  
  78.     if (!RawDev || message->body.diskVecCount == 1) {
  79.         for (i = 0; i < message->body.diskVecCount; i++) {
  80.             ioPageVec[i].iov_base = ShmAddress+(int)message->body.diskVec[i].bufIndex;
  81.             ioPageVec[i].iov_len = (int)message->body.diskVec[i].length;
  82.         }
  83.  
  84.         // return the size of the vector
  85.         vecSize = message->body.diskVecCount;
  86.         return;
  87.     }
  88.     
  89.     SM_ASSERT(LEVEL_3, BlockBuf != NULL);
  90.  
  91.     i = 0;
  92.     ioPageVec[0].iov_base = BlockBuf;
  93.     while(i < message->body.diskVecCount) {
  94.  
  95.         /* Include this check only for the disk process because
  96.          * Shmstruct doesn't exist in the server process.  The check
  97.          * is unnecessary in the single process case anyway.
  98.          */
  99. #    if defined(mips) || defined (vax)
  100.         SM_ASSERT(LEVEL_3, ((message->body.diskVec[i].bufIndex < Shmstruct.sm_size) && (message->body.diskVec[i].bufIndex >= 0)) );
  101. #    elif defined(sparc) || defined(_AIX) || defined(hpux) || defined(linux)
  102.         SM_ASSERT(LEVEL_3, ((message->body.diskVec[i].bufIndex < Shmstruct.shm_segsz) && (message->body.diskVec[i].bufIndex >= 0)) );
  103. #    elif !(defined(mips) || defined (vax) || defined(sparc) || defined(_AIX) || defined(hpux) || defined(linux))
  104.         unsupported
  105. #    else
  106.         /* can't put the else part here because ultrix cpp is broken */
  107. #    endif
  108.  
  109.         if ( (amountInBuf + message->body.diskVec[i].length) > BlockBufSize) {
  110.             break;  /* block buffer is full */
  111.         }
  112.  
  113.         memcpy(BlockBuf+amountInBuf, ShmAddress+(int)message->body.diskVec[i].bufIndex, message->body.diskVec[i].length);
  114.  
  115.         amountInBuf += message->body.diskVec[i].length;
  116.         i++;
  117.     }
  118.     diskVecUsed = i;
  119.     SM_ASSERT(LEVEL_3, diskVecUsed>0);
  120.     SM_ASSERT(LEVEL_3, (amountInBuf <= BlockBufSize) );
  121.     ioPageVec[0].iov_len = amountInBuf;
  122.  
  123.     for (i = diskVecUsed; i < message->body.diskVecCount; i++) {
  124.         ioPageVec[i-diskVecUsed+1].iov_base = ShmAddress+(int)message->body.diskVec[i].bufIndex;
  125.         ioPageVec[i-diskVecUsed+1].iov_len = (int)message->body.diskVec[i].length;
  126.     }
  127.     // return the size of the vector
  128.     vecSize = 1 + message->body.diskVecCount-diskVecUsed;
  129.  
  130. } /* generateVector */
  131.  
  132.  
  133. #else  /* DISKPROC_MAKE */
  134.  
  135. static void
  136. generateVector(
  137.     DISKMSG    *message,
  138.     struct  iovec  ioPageVec[],
  139.     int&    vecSize 
  140. )
  141. {
  142.     int i;
  143.  
  144.     for (i = 0; i < message->body.diskVecCount; i++) {
  145.         ioPageVec[i].iov_base = ShmAddress+(int)message->body.diskVec[i].bufIndex;
  146.         ioPageVec[i].iov_len = (int)message->body.diskVec[i].length;
  147.     }
  148.  
  149.     // return the size of the vector
  150.     vecSize = message->body.diskVecCount;
  151.  
  152. } /* generateVector */
  153.  
  154. #endif /* DISKPROC_MAKE */
  155.  
  156.  
  157.  void
  158. writeLocalDisk (
  159.     DISKMSG    *message
  160. )
  161. {
  162.     int        length;
  163.     int        writeLength;
  164.     struct  iovec  ioPageVec[MAX_DISK_IOVEC];
  165.     int        vecSize;
  166.     int        i;
  167.  
  168.  
  169.     TRPRINT(TR_DISKRW, TR_LEVEL_1, ("writing at:%d numVectors:%d",
  170.             message->body.offset, message->body.diskVecCount));
  171.  
  172.     /*
  173.      *    attempt to seek to the place in the file
  174.      */
  175.     if (lseek(Fd, (int)(message->body.offset), L_SET) < 0)    {
  176.  
  177.         /*
  178.          *    print an error message
  179.          */
  180.         SM_ERROR(TYPE_SYS, errno);
  181.  
  182.         /*
  183.          *    reply in the negative
  184.          */
  185.         if (errno == 0) SM_ERROR(TYPE_FATAL, esmINTERNAL);
  186.         message->header.params.out.errno = errno;
  187.         message->diskmagic = DISK_MESSAGE_MAGIC;
  188.         replyDiskMessage(message);
  189.     }
  190.  
  191.     /*
  192.      *    Write each page separately.  See code in "ifdef JUNK" for
  193.      *    how to use a vectored write.  
  194.      *  If this is the disk process we first call collectVector
  195.      *    which copies the pages to a contiguous location in memory
  196.      *    and adjusts the vector.
  197.      */
  198.     SM_ASSERT(LEVEL_3, (message->body.diskVecCount > 0) &&
  199.                        (message->body.diskVecCount <= MAX_DISK_IOVEC));
  200.     generateVector(message, ioPageVec, vecSize/*OUT*/);
  201.  
  202.     for (i = 0; i < vecSize; i++) {
  203.  
  204.         /* attempt to write the disk */
  205.         if ((writeLength = write(Fd, ioPageVec[i].iov_base, ioPageVec[i].iov_len)) < ioPageVec[i].iov_len)    {
  206.  
  207.             /* print an error message */
  208.             SM_ERROR(TYPE_SYS, errno);
  209.  
  210.             /* reply in the negative */
  211.             if (errno == 0) SM_ERROR(TYPE_FATAL, esmINTERNAL);
  212.             message->header.params.out.errno = (FOUR)errno;
  213.             message->diskmagic = DISK_MESSAGE_MAGIC;
  214.             replyDiskMessage(message);
  215.         }
  216.     }
  217.  
  218.     TRPRINT(TR_DISKRW, TR_LEVEL_2, ("write successful"));
  219.  
  220.     /*
  221.      *    reply in the positive
  222.      */
  223.     message->header.params.out.errno = esmNOERROR;
  224.     message->diskmagic = DISK_MESSAGE_MAGIC;
  225.     replyDiskMessage(message);
  226.  
  227. }
  228.  
  229. /*
  230.  *    The following code does not work at this time because
  231.  *    writev does not work to a raw device.  
  232.  */
  233. #ifdef JUNK
  234.  
  235.     /*
  236.      *    Generate the io vector for the write
  237.      */
  238.     SM_ASSERT(LEVEL_3, (message->body.diskVecCount > 0) &&
  239.                        (message->body.diskVecCount <= MAX_DISK_IOVEC));
  240.     length = 0;
  241.     for (i = 0; i < message->body.diskVecCount; i++) {
  242.  
  243. #ifdef DISKPROC_MAKE
  244.         /* Include this check only for the disk process because
  245.          * Shmstruct doesn't exist in the server process.  The check
  246.          * is unnecessary in the single process case anyway.
  247.          */
  248. #    if defined(mips) || defined (vax)
  249.         SM_ASSERT(LEVEL_3, ((message->body.diskVec[i].bufIndex < Shmstruct.sm_size) && (message->body.diskVec[i].bufIndex >= 0)) );
  250. #    elif defined(sparc)
  251.         SM_ASSERT(LEVEL_3, ((message->body.diskVec[i].bufIndex < Shmstruct.shm_segsz) && (message->body.diskVec[i].bufIndex >= 0)) );
  252. #    elif !(defined(mips) || defined (vax) || defined(sparc))
  253.         unsupported
  254. #    else
  255.         /* can't put the else part here because ultrix cpp is broken */
  256. #    endif
  257. #endif DISKPROC_MAKE
  258.  
  259.         ioPageVec[i].iov_base = ShmAddress+(int)message->body.diskVec[i].bufIndex;
  260.         ioPageVec[i].iov_len = message->body.diskVec[i].length;
  261.  
  262.         /* pull the length out of the message */
  263.         length += message->body.diskVec[i].length;
  264.     }
  265.  
  266.     /*
  267.      *    attempt to write the disk
  268.      */
  269.     if ((writeLength = writev(Fd, ioPageVec, message->body.diskVecCount)) < length)    {
  270.  
  271.         /*
  272.          *    print an error message
  273.          */
  274.         SM_ERROR(TYPE_SYS, errno);
  275.  
  276.         /*
  277.          *    reply in the negative
  278.          */
  279.         if (errno == 0) SM_ERROR(TYPE_FATAL, esmINTERNAL);
  280.         message->header.params.out.errno = errno;
  281.         message->diskmagic = DISK_MESSAGE_MAGIC;
  282.         replyDiskMessage(message);
  283.  
  284.     } else {
  285.  
  286.         TRPRINT(TR_DISKRW, TR_LEVEL_2, ("write successful"));
  287.  
  288.         /*
  289.          *    reply in the positive
  290.          */
  291.         if (errno == 0) SM_ERROR(TYPE_FATAL, esmINTERNAL);
  292.         message->header.params.out.errno = esmNOERROR;
  293.         message->diskmagic = DISK_MESSAGE_MAGIC;
  294.         replyDiskMessage(message);
  295.     }
  296. #endif /* JUNK */
  297.